from ferris import BasicModel
from google.appengine.ext import ndb
from app.models import util


class Feature(BasicModel):
    """
    Models features of an issue. Features are appearances of columns in an
    issue, can have a description and the name of an artist related to its
    contents.
    """
    issue = ndb.KeyProperty(kind="Issue", required=True)
    column = ndb.KeyProperty(kind="Column", required=True)
    description = ndb.StringProperty(required=True)
    description_sort = ndb.ComputedProperty(lambda self:
                                            util.homogenize_name(
                                                self.description))
    artist = ndb.KeyProperty(kind="Artist")
    publication_day = ndb.ComputedProperty(lambda self:
                                           self.get_publication_day())
    search_terms = ndb.ComputedProperty(lambda self:
                                        self.create_search_terms(),
                                        repeated=True)

    def get_publication_day(self):
        """
        Retrieve the issue's publication day, to be stored as a computed
        property used for sorting.
        """
        return self.issue.get().publication_day

    def create_search_terms(self):
        """
        Create a list of unique search terms from the feature description and
        artist name (if any) to be used for partial string match.
        """
        search_words = self.description
        if self.artist:
            search_words += ' ' + self.artist.get().name
        return util.create_search_terms(search_words)

    @classmethod
    def list_query(cls, query=None):
        """
        Queries all issues with an optional query string, ordered by the issue
        number.
        """
        if query:
            search_args = util.prepare_search_args(query)
            results = cls.query(cls.search_terms.IN(search_args))
        else:
            results = cls.query()

        return results.order(-cls.publication_day, cls.description_sort,
                             cls.key)

